package com.example.speeddating.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.speeddating.algorithm.AlgorithmUtils;
import com.example.speeddating.constants.Constants;
import com.example.speeddating.constants.TaoHuaConstant;
import com.example.speeddating.entity.*;
import com.example.speeddating.mapper.ArticleImageMapper;
import com.example.speeddating.mapper.ArticleMapper;
import com.example.speeddating.mapper.LikeMapper;
import com.example.speeddating.mapper.UserMapper;
import com.example.speeddating.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.util.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 * @author tina
 * @since 2023-06-28 11:14:33
 */
@Slf4j
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {


    @Autowired
    private TaohuaDetailService taohuaDetailService;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ArticleImageService articleImageService;

    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private FollowTopicService followTopicService;

    @Autowired
    private UserService userService;

    @Autowired
    private TopicService topicService;

    @Override
    public ArrayList<String> getArticleImage(Long articleId){
        ArticleImage articleImage = articleImageService.getArticleImage(articleId);
        ArrayList<String> images = new ArrayList<>();
        if (articleImage!=null){
            if(articleImage.getImage1()!=null){
                images.add(articleImage.getImage1());
            }
            if(articleImage.getImage2()!=null){
                images.add(articleImage.getImage2());
            }
            if(articleImage.getImage3()!=null){
                images.add(articleImage.getImage3());
            }
            if(articleImage.getImage4()!=null){
                images.add(articleImage.getImage4());
            }
            if(articleImage.getImage5()!=null){
                images.add(articleImage.getImage5());
            }
        }

        return images;
    }

    private Page<Object> handleArticle(Page<Article> articlePage,Long userId){
        List<Article> articleList = articlePage.getRecords();
        Page<Object> objectPage = new Page<>();
        ArrayList<Object> list = new ArrayList<>();
        articleList.forEach(article -> {
            User user = userMapper.selectById(article.getUserId());
            if (userId!=null){
                if (Long.compare(userId, article.getUserId()) == 0) {
                    user.setIsFollowed(null);
                } else {
                    Integer focus = userMapper.selectIsFocus(userId, article.getUserId());//查询是否关注发布文章的user
                    if (focus != 0) {
                        user.setIsFollowed(true);
                    } else {
                        user.setIsFollowed(false);
                    }
                }

                //文章是否点赞
                Integer integer = likeMapper.selectIsLike2(article.getId(), userId);
                if (integer != 0) {
                    article.setIsLike(true);
                } else {
                    article.setIsLike(false);
                }
            }
            user.setArticle(article);
            ArrayList<String> articleImage = getArticleImage(article.getId());
            article.setImages(articleImage);
            list.add(user);
    });
        objectPage.setRecords(list);
        objectPage.setCurrent(articlePage.getCurrent());
        objectPage.setPages(articlePage.getPages());
        return objectPage;
    }


    @Override
    public Page recommendList(int pageSize, int pageNum,Long userId) {
        if (userId==null){  //未登录 直接查询
            Page<Article> articlePage = selectArticles(pageSize, pageNum);
            return handleArticle(articlePage, userId);
        }else {
            //根据用户标签推荐用户  相似用户的文章和它们点赞的文章
            Page<Long> similarUser = userService.getSimilarUser(pageNum, pageSize, userId, 5);
            if (similarUser==null||similarUser.getRecords().size()<1){  //没有数据了
                return new Page<>();
            }
            //获取他们点赞的文章
            LambdaQueryWrapper<Like> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Like::getUserId,similarUser.getRecords());
            queryWrapper.select(Like::getArticleId);
            List<Like> likes = likeMapper.selectList(queryWrapper);
            List<Article> articleList = new ArrayList<>();
            likes.forEach(item->{
                if (item==null)return;
                Article article = articleMapper.selectArticleById(item.getArticleId());
                if (article!=null){
                    articleList.add(article);
                }
            });
            //去重
            Map<Long, List<Article>> userIdUserListMap = new HashMap<>();
            if (articleList!=null){
                userIdUserListMap = articleList
                .stream()
                .collect(Collectors.groupingBy(Article::getId));
            }
            List<Article> finalArticleList = new ArrayList<>();
            for (Map.Entry<Long, List<Article>> longListEntry : userIdUserListMap.entrySet()) {
                finalArticleList.add(longListEntry.getValue().get(0));
            }
            Page<Article> articlePage = new Page<>();
            articlePage.setPages(similarUser.getPages());
            articlePage.setCurrent(similarUser.getCurrent());
            articlePage.setRecords(finalArticleList);
            return handleArticle(articlePage,userId);
        }
    }

    @Override
    public User selectArticleById(Long id,Long userId) {
        Article article = articleMapper.selectArticleById(id);
        ArrayList<String> articleImage = getArticleImage(id);
        article.setImages(articleImage);
        User user = userMapper.selectById(article.getUserId());
        user.setArticle(article);
        if (userId!=null){
            if (userId.equals(article.getUserId())){
                user.setIsFollowed(null);
            }else {
                Integer focus = userMapper.selectIsFocus(userId, article.getUserId());//查询是否关注发布文章的user
                if (focus!=0){
                    user.setIsFollowed(true);
                }else {
                    user.setIsFollowed(false);
                }
            }
        }
        return user;
    }


    @Override
    public Page topicArticleList(int pageSize, int pageNum, Long userId, Long topic_id) {
        Page<User> objectPage = new Page<>();
        Page<Article> articlePage = new Page<>(pageNum, pageSize);
        Page<Article> articles = articleMapper.selectArticleByTopicId(articlePage, topic_id);
        ArrayList<User> list = new ArrayList<>();
        articles.getRecords().forEach(article -> {
            User user = userMapper.selectById(article.getUserId());
            if (userId!=null){ //查询是否关注它
                if (userId.equals(article.getUserId())){
                    user.setIsFollowed(null);
                }else {
                    Integer focus = userMapper.selectIsFocus(userId, article.getUserId());//查询是否关注发布文章的user
                    if (focus!=0){
                        user.setIsFollowed(true);
                    }else {
                        user.setIsFollowed(false);
                    }
                }

                //文章是否点赞
                Integer integer = likeMapper.selectIsLike2(article.getId(), userId);
                if (integer!=0){
                    article.setIsLike(true);
                }else {
                    article.setIsLike(false);
                }
            }
            user.setArticle(article);
            ArrayList<String> articleImage = getArticleImage(article.getId());
            article.setImages(articleImage);
            list.add(user);
        });
        objectPage.setTotal(articles.getTotal());
        objectPage.setPages(articles.getPages());
        objectPage.setCurrent(articlePage.getCurrent());
        objectPage.setRecords(list);
        return objectPage;
    }

    @Override
    public Page topicArticleList(int pageSize, int pageNum, Long userId) {
        Page<Object> objectPage = new Page<>();
        Page<Article> articlePage = new Page<>(pageNum, pageSize);
        Page<Article> articles = articleMapper.selectArticleByUserId(articlePage,userId);
        ArrayList<Object> list = new ArrayList<>();
        articles.getRecords().forEach(article -> {
            User user = userMapper.selectById(article.getUserId());
            user.setIsFollowed(null);
            //文章是否点赞
            Integer integer = likeMapper.selectIsLike2(article.getId(), userId);
            if (integer != 0) {
                article.setIsLike(true);
            } else {
                article.setIsLike(false);
            }
            user.setArticle(article);
            ArrayList<String> articleImage = getArticleImage(article.getId());
            article.setImages(articleImage);
            list.add(user);
        });
        objectPage.setCurrent(pageNum);
        objectPage.setTotal(articles.getTotal());
        objectPage.setPages(articles.getPages());
        return objectPage.setRecords(list);
    }

    @Override
    public Page focusArticleList(int pageSize, int pageNum, Long userId) {
        Page<Object> objectPage = new Page<>();
        Page<Article> articlePage = new Page<>(pageNum, pageSize);
        Page<Article> articles = articleMapper.selectFollowArticleList(articlePage,userId);
        ArrayList<Object> list = new ArrayList<>();
        articles.getRecords().forEach(article -> {
            User user = userMapper.selectById(article.getUserId());
            //文章是否点赞
            Integer integer = likeMapper.selectIsLike2(article.getId(), userId);
            if (integer != 0) {
                article.setIsLike(true);
            } else {
                article.setIsLike(false);
            }
            user.setArticle(article);
            ArrayList<String> articleImage = getArticleImage(article.getId());
            article.setImages(articleImage);
            list.add(user);
        });
        objectPage.setTotal(articles.getTotal());
        objectPage.setPages(articles.getPages());
        return objectPage.setRecords(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishArticle(Article article) {
        articleMapper.insert(article);
        topicService.incrementJoinedNum(article.getTopicId()); //添加参与人数
        topicService.incrementTopicTot(article.getTopicId(), Constants.HOT_TYPE_PUBLISH);//添加热度
        followTopicService.insertFollowTopic(article.getUserId(),article.getTopicId());//用户参与
        taohuaDetailService.insertTaohuaDetail(TaoHuaConstant.Type_4,article.getUserId());//桃花
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteArticle(long id) {
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        articleMapper.delete(queryWrapper);
    }

    @Override
    public Page<Article> selectArticles(int pageSize, int pageNum) {
        Page<Article> articlePage = new Page<>(pageNum, pageSize);
        Page<Article> articles = articleMapper.selectArticle(articlePage);

        ArrayList<Object> list = new ArrayList<>();
        articles.getRecords().forEach(article -> {
            User user = userMapper.selectById(article.getUserId());
            user.setArticle(article);
            ArrayList<String> articleImage = getArticleImage(article.getId());
            article.setImages(articleImage);
            list.add(user);
        });
        return articles;
    }
}
